package com.wandian.texas.dao.Impl;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

import com.wandian.texas.GameData;
import com.wandian.texas.GameMgr;
import com.wandian.texas.GameServer;
import com.wandian.texas.ResPool;
import com.wandian.texas.TestGamePool;
import com.wandian.texas.db.DBMgr;
import com.wandian.texas.db.DbWatch;
import com.wandian.texas.db.PageInfo;
import com.wandian.texas.db.Result;
import com.wandian.texas.db.WandianBaseDao;
import com.wandian.texas.demo.Test.StepEntity;
import com.wandian.texas.entity.ConfigEntity;
import com.wandian.texas.entity.CornucopiaEntity;
import com.wandian.texas.entity.GameRoomEntity;
import com.wandian.texas.entity.UserGameEntity;
import com.wandian.texas.entity.UserInfoEntity;
import com.wandian.util.Log;

/**
 * @author long
 * @Create 2012-10-27 上午10:59:55
 * @QQ 108232706
 * @version 1.0
 * @description GameRoomDaoImpl游戏操作数据库
 */
public class GameRoomDaoImpl extends WandianBaseDao {

	public GameRoomDaoImpl(DBMgr _dbMgr) {
		super(_dbMgr);
	}

	/**
	 * 添加大小盲，新人下注
	 * 
	 * @param gameRoom
	 * @return
	 */
	/*public boolean addGameRoom(GameRoomEntity gameRoom) {
		int id = 0;
		if (gameRoom == null) {
			return false;
		}
		String SeatUserIds = String.valueOf(gameRoom.getSeatUserId(1));
		String SeatIdx = String.valueOf(gameRoom.getSeatAcountId(1));
		for (int i = 2; i < 10; i++) {
			SeatUserIds += "," + gameRoom.getSeatUserId(i);
			SeatIdx += "," + gameRoom.getSeatAcountId(i);
		}
		if (gameRoom.beginAdd()) {
			String sql = " INSERT INTO Game_BeginLog(ServerId,RoomId,RoomName,PlayerNum,SeatCount,prevId,PublicCard,SeatUserIds,SeatIdx,DealerId," + "MinBindUserId,MinBind,MaxBindUserId,MaxBind,DlayTime,MinStake,MaxStake,NewChip,NewUserIds,WatchUserIds,StartChips," + "SeatUserId1,SeatUserId2,SeatUserId3,SeatUserId4,SeatUserId5,SeatUserId6,SeatUserId7,SeatUserId8,SeatUserId9," + "HandCard1,HandCard2,HandCard3,HandCard4,HandCard5,HandCard6,HandCard7,HandCard8,HandCard9,"
					+ "IsSave,StartTime)  VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
			id = super.execLastId2(sql, gameRoom.ServerId, gameRoom.RoomId, gameRoom.RoomName, gameRoom.PlayerNum, gameRoom.SeatCount, gameRoom.prevId, gameRoom.getpublicCard(), gameRoom.getDealerId(), gameRoom.MinBindUserId, gameRoom.MinBind, gameRoom.MaxBindUserId, gameRoom.MaxBind, gameRoom.DlayTime, gameRoom.MinStake, gameRoom.MaxStake, gameRoom.NewChip, gameRoom.NewUserIds, gameRoom.WatchUserIds, gameRoom.StartChips, gameRoom.getSeatUserId(1), gameRoom.getSeatUserId(2),
					gameRoom.getSeatUserId(3), gameRoom.getSeatUserId(4), gameRoom.getSeatUserId(5), gameRoom.getSeatUserId(6), gameRoom.getSeatUserId(7), gameRoom.getSeatUserId(8), gameRoom.getSeatUserId(9), gameRoom.getHandCard(1), gameRoom.getHandCard(2), gameRoom.getHandCard(3), gameRoom.getHandCard(4), gameRoom.getHandCard(5), gameRoom.getHandCard(6), gameRoom.getHandCard(7), gameRoom.getHandCard(8), gameRoom.getHandCard(9), 0, new Date(System.currentTimeMillis()));
			gameRoom.GameId = id;
			gameRoom.commitAdd(id > 0);
		}
		return id > 0;
	}*/
	public ArrayList<StepEntity> getGameStep(int gameid) {
		String sqlText = "SELECT * FROM  [Mutil_TexasPoker].[dbo].Game_StepLog WHERE  GameId=? and step>0  order by step ;";
		PreparedStatement pstmt = this.execQuery2(sqlText, gameid);
		ResultSet rs = null;
		ArrayList<StepEntity> steps = new ArrayList<StepEntity>();
		if (pstmt != null) {
			try {
				rs = pstmt.executeQuery();
				if (rs != null) {
					StepEntity step;
					while (rs.next()) {
						step = new StepEntity();
						step.actionType = rs.getInt("ActionType");
						step.userid = rs.getInt("UserId");
						step.step = rs.getInt("Step");
						step.giveChip = rs.getFloat("GiveChip");
						step.stake = rs.getFloat("Stake");
						step.seatChip = rs.getFloat("SiteChip");
						steps.add(step);
					}
				}
			} catch (SQLException e) {
				Log.error("执行出错" + sqlText, e);
			} finally {
				closeConn(pstmt, rs);
			}
		}
		return steps;
	}

	public void getGameBaseInfo(int gameid) {
		String sqlText = "SELECT * FROM  dbo.Game_BeginLog WHERE  Id=?;";
		PreparedStatement pstmt = this.execQuery2(sqlText, gameid);
		ResultSet rs = null;
		if (pstmt != null) {
			try {
				rs = pstmt.executeQuery();
				if (rs != null) {
					if (rs.next()) {
						String[] pokers = rs.getString("PokerIndexs").split(",");
						String[] seats = rs.getString("SeatUserIds").split(",");
						int[] PokerIndexs = new int[pokers.length];
						for (int i = 0; i < pokers.length; i++) {
							PokerIndexs[i] = Integer.valueOf(pokers[i].trim());
						}
						int[] seatsIdx = new int[seats.length];
						for (int i = 0; i < seats.length; i++) {
							seatsIdx[i] = Integer.valueOf(seats[i].trim());
						}
						TestGamePool.publicAndSeatPokerIndex = PokerIndexs;
						TestGamePool.seatIdx = seatsIdx;
						TestGamePool.setDealerId = rs.getInt("DealerId");

					}
				}
			} catch (SQLException e) {
				Log.error("执行出错" + sqlText, e);
			} finally {
				closeConn(pstmt, rs);
			}
		}
	}

	public boolean addBeginGameLog(GameRoomEntity gameRoom) {
		if (gameRoom == null) {
			return false;
		}
		String seatUserIds = String.valueOf(gameRoom.getSeatUserId(1));
		String seatAccountIds = String.valueOf(gameRoom.getSeatAcountId(1));
		for (int i = 2; i <= 9; i++) {
			seatUserIds += "," + gameRoom.getSeatUserId(i);
			seatAccountIds += "," + gameRoom.getSeatAcountId(i);
		}
		String pokerIndexs = "";
		pokerIndexs += gameRoom.publicAndSeatPokerIndex[0];
		for (int i = 1; i < gameRoom.publicAndSeatPokerIndex.length; i++) {
			pokerIndexs += "," + gameRoom.publicAndSeatPokerIndex[i];
		}
		// 方便查询,多一个字段
		gameRoom.GameId = this.executeInsert("sp_AddBeginGameLog", DBMgr.TexasPokerDB, gameRoom.ServerId, gameRoom.RoomCode, gameRoom.RoomId, gameRoom.RoomName, gameRoom.PlayerNum, gameRoom.SeatCount, gameRoom.prevId, gameRoom.getpublicCard(), seatUserIds, seatAccountIds, gameRoom.getDealerId(), gameRoom.MinBindUserId, gameRoom.MinBind, gameRoom.MaxBindUserId, gameRoom.MaxBind, gameRoom.DlayTime, gameRoom.MinStake, gameRoom.MaxStake, gameRoom.NewChip, gameRoom.NewUserIds, gameRoom.WatchUserIds, gameRoom.StartChips, gameRoom.getSeatUserId(1), gameRoom.getSeatUserId(2), gameRoom.getSeatUserId(3), gameRoom.getSeatUserId(4), gameRoom.getSeatUserId(5), gameRoom.getSeatUserId(6), gameRoom.getSeatUserId(7), gameRoom.getSeatUserId(8), gameRoom.getSeatUserId(9), gameRoom.getHandCard(1),
				gameRoom.getHandCard(2), gameRoom.getHandCard(3), gameRoom.getHandCard(4), gameRoom.getHandCard(5), gameRoom.getHandCard(6), gameRoom.getHandCard(7), gameRoom.getHandCard(8), gameRoom.getHandCard(9), pokerIndexs);
		return gameRoom.GameId > 0;
	}

	private final String sql_SaveGameRoom = " UPDATE [Mutil_TexasPoker].[dbo].Game_BeginLog SET IsSave=1 where Id=?; ";

	public boolean saveGameRoom(GameRoomEntity gameRoom) {
		if (gameRoom.GameId < 1)
			return false;

		int result = this.execNoneQuery2(sql_SaveGameRoom, gameRoom.GameId);
		if (result > 0)
			return true;
		return false;
	}

	private final String sql_AddExchange = "INSERT INTO [Mutil_TexasPoker].[dbo].Game_TableLog (ServerId ,RoomdId,SeatId ,GameId ,UserId,idx,Money ,Stake,LeftMoney,Win,CreateTime,Memo) VALUES(?,?,?,?,?,?,?,?,?,?,?,?) ";
	private final String sql_UpdatePlayer = "1UPDATE  [Mutil_TexasPoker].[dbo].PlayerInfo SET MONEY=?,STAKE=?,GameBet=? WHERE userid=?";

	/**
	 * 金钱变化记录
	 * 
	 * @param roomid
	 * @param gameid
	 * @param user
	 * @param win
	 * @return
	 */
	public boolean addExchange(int roomid, int gameid, int seatId, UserInfoEntity user, float win, String memo) {
		// 此表money已无用
		boolean result = executeUpdate("sp_AddTableLog", DBMgr.TexasPokerDB, GameData.SERVER.ServerId, roomid, seatId, gameid, user.userId, user.AccountId, user.money, user.stake, user.money + user.stake, win, memo);
		// 存储过程去更新前，同时通知大厅
		// --可能游戏没有结束，玩家站起来了，所以在gameuser里没有他，那么就无法通过sp_AddPlayMoneyLog清除GameBet
		if (result) {
			result = executeUpdate("sp_UpdatePlayer", DBMgr.TexasPokerDB, user.userId, user.money, user.stake, 0);
		}
		return result;

	}

	public boolean addSitStandLog(int roomid, int gameid, int seatId, UserInfoEntity user, float win, String memo) {
		if (executeProcedureReturn("sp_SaveGameWinner", DBMgr.TexasPokerDB, GameData.SERVER.ServerId, roomid, seatId, gameid, user.userId, user.AccountId, user.money, user.stake, user.money + user.stake, win, memo) != 1) {
			throw new IllegalArgumentException("addSitStandLog error");
		}
		return true;
	}

	public boolean saveGameWinner(GameRoomEntity gameRoom, int roomid, int gameid, int seatId, UserInfoEntity user, float win, String memo) {
		if (executeProcedureReturn("sp_SaveGameWinner", DBMgr.TexasPokerDB, GameData.SERVER.ServerId, roomid, seatId, gameid, user.userId, user.AccountId, user.money, user.stake, user.money + user.stake, win, memo) != 1) {
			gameRoom.errorStatus = "saveGameWinner,sp_AddTableLog,失败,roomid:" + gameRoom.RoomId + " gameid:" + gameRoom.GameId;
			Log.error(gameRoom.errorStatus);
			GameMgr.addErrorGame(gameRoom);
			throw new IllegalArgumentException(gameRoom.errorStatus);
		}
		return true;

	}

	public boolean addExchange0(int roomid, int gameid, int seatId, UserInfoEntity user, float win, String memo) {
		// 此表money已无用
		boolean result = execNoneQuery2(sql_AddExchange, DBMgr.TexasPokerDB, GameData.SERVER.ServerId, roomid, seatId, gameid, user.userId, user.AccountId, user.money, user.stake, user.money + user.stake, win, new Timestamp(System.currentTimeMillis()), memo) > -1;
		// 存储过程去更新前，同时通知大厅
		// --可能游戏没有结束，玩家站起来了，所以在gameuser里没有他，那么就无法通过sp_AddPlayMoneyLog清除GameBet

		result = execNoneQuery2(sql_UpdatePlayer, DBMgr.TexasPokerDB, user.money, user.stake, 0, user.userId) > -1;
		return result;

	}

	private final String sql_AddGameLog = " INSERT INTO [Mutil_TexasPoker].[dbo].[Game_StepLog](GameId,ServerId,Step,UserId,idx,SeatId,RoundNum,ActionType,LeftTime,GiveChip,SiteChip,Stake,TotalChip,CurrentState,CreateTime,Memo)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";

	public boolean addGameLog0(int gameid, int step, UserInfoEntity user, int RoundNum, int LeftTime, float callChip, float curSeatChip, float totalChip, String memo) {

		return execNoneQuery2(sql_AddGameLog, DBMgr.TexasPokerDB, gameid,/* GameData.SERVER.ServerId */1, step, user.userId, user.AccountId, user.seatId, RoundNum, (byte) user.lastAction, LeftTime, callChip, curSeatChip, user.stake, totalChip, user.state, new Timestamp(System.currentTimeMillis()), memo) > -1;
	}

	public boolean addGameLog(GameRoomEntity gameRoom, int gameid, int step, UserInfoEntity user, int RoundNum, int LeftTime, float callChip, float curSeatChip, float totalChip, String memo) {

		if (!executeUpdate("sp_AddGameLog", DBMgr.TexasPokerDB, gameid, GameData.SERVER.ServerId, step, user.userId, user.AccountId, user.seatId, RoundNum, (byte) user.lastAction, LeftTime, callChip, curSeatChip, user.stake, totalChip, user.state, memo)) {
			gameRoom.errorStatus = "addGameLog,sp_AddGameLog,失败,roomid:" + gameRoom.RoomId + " gameid:" + gameRoom.GameId;
			Log.error(gameRoom.errorStatus);
			GameMgr.addErrorGame(gameRoom);
			throw new IllegalArgumentException(gameRoom.errorStatus);
		}
		return true;
	}

	/**
	 * 更新游戏结果，边池状态以及抽成，聚宝盆，玩家所得
	 * 
	 * @param game
	 */
	public void UpdateBonusPools(GameRoomEntity game) {
		String produceName = "sp_AddEndGameLog";
		String BonusPoolsInfo = "";
		String SystemWinPools = "";
		String winners = "";
		String accountIds = "";
		String WinMoneys = "";
		String MaxHands = "";
		int SystemWin = 0;
		UserGameEntity[] winnerList;
		UserGameEntity user;
		for (int i = 0; i < game.BonusPools.length; i++) {
			if (game.BonusPools[i] > 0) {
				//				winnerList = game.winnerMap.get(i);
				winnerList = game.winnerMap[i];
				if (i == 0) {
					BonusPoolsInfo += game.BonusPools[i];
					SystemWinPools += game.SystemWinPools[i];
				} else {
					BonusPoolsInfo += "|" + game.BonusPools[i];
					SystemWinPools += "|" + game.SystemWinPools[i];
					winners += "|";
					accountIds += "|";
					WinMoneys += "|";
					MaxHands += "|";
				}
				for (int j = 0; j < winnerList.length; j++) {
					user = winnerList[j];
					if (user == null)
						break;
					if (j != 0) {
						winners += ",";
						WinMoneys += ",";
						MaxHands += ",";
						accountIds += ",";
					}
					winners += user.user.userId;
					accountIds += user.user.AccountId;
					WinMoneys += user.bonusWin[i];
					MaxHands += user.getMaxCards();
				}
				SystemWin += game.SystemWinPools[i];
			} else {
				break;
			}
		}
		// int ToCornucopia = Math.round(SystemWin * GameData.ToCornucopiaRate);
		/*CallableStatement stmt = this.execProduce2(produceName, game.GameId, BonusPoolsInfo, SystemWinPools, SystemWin, winners, WinMoneys, MaxHands);
		ResultSet rs = null;
		if (stmt != null) {
			try {
				stmt.execute(); // 是否有结果集返回
				if(stmt.getInt(1)!=0){
					Log.error("插入EndGameLog错误");
				}
			} catch (SQLException e) {
				Log.error("[DataBase][database:" + dbMgr.getCurrentDbName()+" dbindex:"+dbMgr.index+ "]执行出错" + produceName, e);
			} finally {
				closeConn(stmt, rs);
			}
		}*/
		// executeUpdate适合只返回影响行的语句
		if (!this.executeUpdate(produceName, DBMgr.TexasPokerDB, game.GameId, BonusPoolsInfo, SystemWinPools, SystemWin, winners, accountIds, WinMoneys, MaxHands)) {
			Log.error("插入EndGameLog错误");
		}
		// 更新聚宝盆，可以采用定时器方式
		GameServer.requestor.requestSendSystemTotalWin(game.RoomId, game.GameId, SystemWin);
		winnerList = null;
		user = null;
	}

	String sql_AddCornucopias = "INSERT INTO [Mutil_TexasPoker].[dbo].t_Cornucopia(ServerId,RoomId,GameId,UserId,NickName,WinMoney,CardType,MaxCards,WinTime) VALUES(?,?,?,?,?,?,?,?,?)";

	/**
	 * 产生了积宝，通过存储过程更新积宝与系统盈利
	 * 
	 * @param Cornucopias
	 */
	public void addCornucopias(ArrayList<CornucopiaEntity> Cornucopias) {
		if (Cornucopias != null && Cornucopias.size() > 0) {
			Connection conn = openConn();
			if (conn == null) {
				return;
			}
			PreparedStatement pstmt = null;
			int[] result = null;

			try {
				conn.setAutoCommit(false);
				// 预编译SQL语句,只编译一回,效率高啊
				pstmt = conn.prepareStatement(sql_AddCornucopias, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
				CornucopiaEntity cornucopia;
				for (int i = 0; i < Cornucopias.size(); i++) {
					cornucopia = Cornucopias.get(i);
					prepareAddBatch(pstmt, cornucopia.ServerId, cornucopia.RoomId, cornucopia.GameId, cornucopia.UserId, cornucopia.NickName, cornucopia.WinMoney, cornucopia.CardType, cornucopia.MaxCards, cornucopia.WinTime);
				}
				result = pstmt.executeBatch();
				conn.setAutoCommit(true);
			} catch (Exception ex) {
				String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), "调用Sql语句" + sql_AddCornucopias + "出错" });
				Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + msg, ex);
			} finally {
				closeConn(conn, pstmt);
			}
			for (int r : result) {
				if (r < 1) {
					Log.error("insert t_Cornucopia error");
				}
			}
		}
	}

	public boolean updateCornucopiasBySp(ArrayList<CornucopiaEntity> Cornucopias) {
		Log.error("未实现功能的方法");
		return true;
	}

	/**
	 * 产生了积宝，通过存储过程更新积宝与系统盈利
	 * 
	 * @param Cornucopias
	 */
	public boolean addCornucopiasBySp(ArrayList<CornucopiaEntity> Cornucopias) {
		Connection conn = openConn();
		if (conn == null) {
			return false;
		}
		String produceName = "sp_AddCornucopias";
		CallableStatement stmt = null;
		ResultSet rs = null;
		int result = 0;
		try {
			stmt = conn.prepareCall(ProcedureNameByReturn(produceName, 8), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			if (stmt == null)
				return false;
			for (int i = 0; i < Cornucopias.size(); i++) {
				stmt.registerOutParameter(1, java.sql.Types.INTEGER);
				stmt.setObject(2, Cornucopias.get(i).ServerId);
				stmt.setObject(3, Cornucopias.get(i).RoomId);
				stmt.setObject(4, Cornucopias.get(i).GameId);
				stmt.setObject(5, Cornucopias.get(i).UserId);
				stmt.setObject(6, Cornucopias.get(i).idx);
				stmt.setObject(7, Cornucopias.get(i).NickName);
				stmt.setObject(8, Cornucopias.get(i).WinMoney);
				stmt.setObject(9, Cornucopias.get(i).CardType);
				stmt.setObject(10, Cornucopias.get(i).MaxCards);
				stmt.execute();
				result = stmt.getInt(1);
				if (result != 0)
					return false;
			}

		} catch (SQLException e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "]执行出错" + produceName, e);
			return false;
		} finally {
			closeConn(stmt, rs);
		}
		return true;
	}

	public Result getPagination(Result result, String strTableName, String strWhere, String strSelectColumns, int currentPage, int pageSize, String orderby, String PKName) {
		Connection conn = openConn();
		if (conn == null) {
			return null;
		}
		CallableStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.prepareCall(ProcedureNameByReturn("sp_Pagination", 8), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			stmt.registerOutParameter(1, java.sql.Types.INTEGER);
			stmt.setObject(2, strTableName);
			stmt.setObject(3, strWhere);
			stmt.setObject(4, strSelectColumns);
			stmt.setObject(5, currentPage);
			stmt.setObject(6, pageSize);
			stmt.setObject(7, orderby);
			stmt.setObject(8, PKName);
			stmt.registerOutParameter(9, java.sql.Types.INTEGER);
			boolean hasResultSet = stmt.execute(); // 是否有结果集返回

			if (hasResultSet) {
				rs = stmt.getResultSet();
				result.IsSuccess = true;
				result.ResultSet = rs;
				if (rs.last()) {
					result.RowSize = rs.getRow();
					rs.beforeFirst();
				}
			} else {
				if (stmt.getMoreResults()) {
					rs = stmt.getResultSet();
					result.IsSuccess = true;
					result.ResultSet = rs;
					if (rs.last()) {
						result.RowSize = rs.getRow();
						rs.beforeFirst();
					}
				}
			}
			result.run();
			result.pageInfo = new PageInfo(currentPage, pageSize, stmt.getInt(9));

		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), "调用Sql语句sp_Pagination出错" });
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + msg, ex);
			result.IsSuccess = false;

		} finally {
			closeConn(conn, stmt);
		}
		return result;
	}

	public Result getSelect(Result result, String strTableName, String strWhere, String strSelectColumns, String orderby) {
		Connection conn = openConn();
		if (conn == null) {
			return null;
		}
		CallableStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.prepareCall(ProcedureNameByReturn("sp_Select", 4), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			stmt.registerOutParameter(1, java.sql.Types.INTEGER);
			stmt.setObject(2, strTableName);
			stmt.setObject(3, strWhere);
			stmt.setObject(4, strSelectColumns);
			stmt.setObject(5, orderby);
			boolean hasResultSet = stmt.execute(); // 是否有结果集返回
			if (hasResultSet) {
				rs = stmt.getResultSet();
				result.IsSuccess = true;
				result.ResultSet = rs;
				if (rs.last()) {
					result.RowSize = rs.getRow();
					rs.beforeFirst();
				}

			} else {
				if (stmt.getMoreResults()) {
					rs = stmt.getResultSet();
					result.IsSuccess = true;
					result.ResultSet = rs;
					if (rs.last()) {
						result.RowSize = rs.getRow();
						rs.beforeFirst();
					}
				}
			}
			result.run();
			if (stmt.getInt(1) == 1)
				result.IsSuccess = false;

		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), "调用Sql语句sp_Pagination出错" });
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + msg, ex);
			result.IsSuccess = false;

		} finally {
			closeConn(conn, stmt);
		}
		return result;
	}

	public Result execProcedure(Result result, String procName, Object... params) {
		DbWatch watch = ResPool.DbWatch(this.dbMgr.index);
		Connection conn = openConn();
		if (conn == null) {
			watch.commit(procName);
			return null;
		}
		CallableStatement stmt = null;
		ResultSet rs = null;
		try {
			stmt = conn.prepareCall(ProcedureName(procName, params.length), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			prepareCallable2(stmt, params);
			boolean hasResultSet = stmt.execute(); // 是否有结果集返回
			if (hasResultSet) {
				rs = stmt.getResultSet();
				result.IsSuccess = true;
				result.ResultSet = rs;
				if (rs.last()) {
					result.RowSize = rs.getRow();
					rs.beforeFirst();
				}

			} else {
				if (stmt.getMoreResults()) {
					rs = stmt.getResultSet();
					result.IsSuccess = true;
					result.ResultSet = rs;
					if (rs.last()) {
						result.RowSize = rs.getRow();
						rs.beforeFirst();
					}
				}
			}
			result.run();
		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), procName });
			Log.error(msg, ex);
			result.IsSuccess = false;

		} finally {
			closeConn(conn, stmt);
			watch.commit(procName);
		}
		return result;
	}

	public Result execFreeProcedure(Result result, int DbType, String procName, int isOutPut, Object... params) {
		result.IsSuccess = false;
		result.ResultSet = null;
		result.stmt = null;
		DbWatch watch = null;
		Connection conn = null;
		CallableStatement stmt = null;
		this.dbMgr.lock.lock();
		try {
			watch = ResPool.DbWatch(this.dbMgr.index);
			this.dbMgr.setCurrentDb(DbType);
			conn = openConn();
			if (conn == null) {
				watch.commit(procName);
				return null;
			}
			stmt = conn.prepareCall(ProcedureName(procName, isOutPut, params.length), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			prepareFreeCallable(stmt, isOutPut, params);
			result.hasResultSet = stmt.execute(); // 是否有结果集返回
			result.stmt = stmt;
			result.run();
		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), procName });
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + msg, ex);
			result.IsSuccess = false;

		} finally {
			closeConn(conn, stmt);
			watch.commit(procName);
			this.dbMgr.lock.unlock();
		}
		return result;
	}

	public Result execBatchProcedure(Result result, int DbType, String procName, int paramsLen, Object dataList) {
		result.IsSuccess = false;
		result.ResultSet = null;
		result.stmt = null;
		DbWatch watch = null;
		Connection conn = null;
		CallableStatement stmt = null;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(DbType);
			watch = ResPool.DbWatch(this.dbMgr.index);
			conn = openConn();
			if (conn == null) {
				watch.commit(procName);
				return null;
			}
			conn.setAutoCommit(false);
			stmt = conn.prepareCall(ProcedureName(procName, paramsLen), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			result.stmt = stmt;
			result.dataList = dataList;
			result.run();// 预备参数
			int[] results = stmt.executeBatch();
			conn.setAutoCommit(true);
			result.RowSize = 0;
			for (int i = 0; i < results.length; i++) {
				result.RowSize += results[i];// 总的影响行数
			}
			result.IsSuccess = true;
		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), procName });
			Log.error(msg, ex);
			result.IsSuccess = false;

		} finally {
			closeConn(conn, stmt);
			watch.commit(procName);
			this.dbMgr.lock.unlock();
		}
		return result;
	}

	/**
	 * 初始化系统全局的配置,对应表t_config
	 */
	public boolean initDbConfig() {
		String produceName = "sp_GetConfig";
		CallableStatement stmt = null;
		ResultSet rs = null;
		ConfigEntity config;
		try {
			stmt = this.execProduce3(produceName, "");
			if (stmt == null)
				return false;
			boolean hasResultSet = stmt.execute(); // 是否有结果集返回
			if (hasResultSet) {
				rs = stmt.getResultSet();
				StringBuilder sbConfig = new StringBuilder("系统全局的配置:");
				while (rs.next()) {
					config = new ConfigEntity();
					config.CKey = rs.getString("Ckey");
					config.CValue = rs.getString("CValue");
					config.FValue = rs.getFloat("FValue");
					GameData.CONFIGS.put(config.CKey, config);
					sbConfig.append(config);
				}
				Log.info(sbConfig.toString());
				// 取出赢家的聚宝盆兑换比例
				GameData.ToCornucopiaRate = GameData.getFloat("ToCornucopiaRate");

				// 中心服初始化加载积宝数据
				// 需要全局数据的，都在这里读取
				GameData.setCornucopia(GameData.getFloat("Cornucopia"));
				GameData.setOffSetCornucopia(GameData.getFloat("OffSetCornucopia"));
				GameData.setSystemTotalWin(GameData.getFloat("SystemTotalWin"));
				GameData.StakeToMoney = GameData.getFloat("StakeToMoney");
				String WinCornucopiaRates = GameData.getString("WinCornucopiaRates");
				String[] rates = WinCornucopiaRates.split(",");// 0,1,2
				for (int i = 0; i < rates.length; i++) {
					GameData.CornucopiaRates[i] = Float.parseFloat(rates[i]);
					// 目前只取前面三个大的牌型做积宝
					if (i > 2) {
						break;
					}
				}
			}
		} catch (SQLException e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "]执行出错" + produceName, e);
			return false;
		} finally {
			closeConn(stmt, rs);
		}
		return true;
	}

	/**
	 * 系统全局的一个配置的ConfigEntity
	 * 
	 * @param key
	 * @return
	 */
	public ConfigEntity getConfig(String key) {
		String produceName = "sp_GetConfig";
		CallableStatement stmt = this.execProduce2(produceName);
		ResultSet rs = null;
		ConfigEntity config = null;
		if (stmt != null) {
			try {
				boolean hasResultSet = stmt.execute(); // 是否有结果集返回
				if (hasResultSet) {
					rs = stmt.getResultSet();
					while (rs != null && rs.last()) {
						config = new ConfigEntity();
						config.CKey = rs.getString("Ckey");
						config.CValue = rs.getString("CValue");
						config.FValue = rs.getFloat("FValue");
					}
				}
			} catch (SQLException e) {
				Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "执行出错" + produceName, e);
				return null;
			} finally {
				closeConn(stmt, rs);
			}
		}
		return config;
	}

	/**
	 * 这里返回影响为1的行，比如带id的查询 更新 插入 删除，如果影响行较多，应该为result>0;
	 * 
	 * @param produceName
	 *            存储过程名字
	 * @param throwException
	 *            当影响行小于1是否报错
	 * @param params
	 *            参数
	 * @return
	 */
	public boolean executeUpdate(String produceName, int dbType, Object... params) {
		int result = 0;
		this.dbMgr.lock.lock();
		this.dbMgr.setCurrentDb(dbType);
		CallableStatement stmt = this.execProduce2(produceName, params);
		try {
			// boolean hasResultSet = stmt.execute(); // 是否有结果集返回
			if (stmt != null) {
				result = stmt.executeUpdate();
			}
			// System.out.println(result);
			// System.out.println("id " + stmt.getGeneratedKeys());
		} catch (Exception e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "执行出错" + produceName, e);
			result = -11;
		} finally {
			closeConn(stmt);
			this.dbMgr.lock.unlock();
		}
		return result == 1;
	}

	public boolean addPlayMoneyLog(GameRoomEntity gameRoom, String produceName, int dbType, Object... params) {
		int result = 0;
		this.dbMgr.lock.lock();
		this.dbMgr.setCurrentDb(dbType);
		CallableStatement stmt = this.execProduce2(produceName, params);
		try {
			// boolean hasResultSet = stmt.execute(); // 是否有结果集返回
			if (stmt != null) {
				result = stmt.executeUpdate();
			}
			// System.out.println(result);
			// System.out.println("id " + stmt.getGeneratedKeys());
		} catch (Exception e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "执行出错" + produceName, e);
			result = -11;
		} finally {
			closeConn(stmt);
			this.dbMgr.lock.unlock();
		}
		if (result != 1) {
			gameRoom.errorStatus = "[GamePool]saveBlindMoney,sp_AddPlayMoneyLog,失败,roomid:" + gameRoom.RoomId + " gameid:" + gameRoom.GameId;
			Log.error(gameRoom.errorStatus);
			GameMgr.addErrorGame(gameRoom);
			throw new IllegalArgumentException(gameRoom.errorStatus);
		}
		return true;
	}

	public int executeNoQuery(String produceName, int dbType, Object... params) {
		int result = 0;
		this.dbMgr.lock.lock();
		CallableStatement stmt = null;
		try {
			this.dbMgr.setCurrentDb(dbType);
			stmt = this.execProduce2(produceName, params);
			if (stmt != null) {
				result = stmt.executeUpdate();
				// System.out.println("id " + stmt.getGeneratedKeys());
			}
		} catch (Exception e) {
			e.printStackTrace();
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "]执行出错" + produceName, e);
			result = -11;
		} finally {
			closeConn(stmt);
			params = null;
			this.dbMgr.lock.unlock();
		}

		return result;
	}

	public int execSql(String sql, int dbType, Object... params) {
		return this.execNoneQuery2(sql, dbType, params);

	}

	public int execQueryCount(String selectSql, int dbType, Object... params) {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		int result = 0;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(dbType);
			pstmt = this.execQuery2(selectSql, params);
			if (pstmt != null) {
				rs = pstmt.executeQuery();
				if (rs != null && rs.last()) {
					result = rs.getRow();

				}
			}
		} catch (SQLException e) {
			result = -1;
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "]执行出错" + selectSql, e);
		} finally {
			closeConn(pstmt, rs);
			this.dbMgr.lock.unlock();
		}
		return result;
	}

	public int executeInsert(String produceName, int dbType, Object... params) {
		int result = 0;
		CallableStatement stmt = null;
		ResultSet rs = null;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(dbType);
			stmt = this.execProduce2(produceName, params);
			if (stmt != null) {
				stmt.execute();
				rs = stmt.getResultSet();
				if (rs.next()) {
					result = rs.getInt(1);
				}
			}
			// result = stmt.getInt(1);
		} catch (Exception e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "] 执行出错" + produceName, e);
			result = 0;
		} finally {
			closeConn(stmt, rs);
			this.dbMgr.lock.unlock();
		}
		return result;
	}

	public int executeProcedureReturn(String produceName, int dbType, Object... params) {
		int result = -100;
		Connection conn = null;
		CallableStatement stmt = null;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(dbType);
			conn = openConn();
			if (conn == null) {
				return result;
			}
			stmt = conn.prepareCall(ProcedureName(produceName, 1, params.length), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			prepareFreeCallable(stmt, 1, params);
			stmt.execute();
			result = stmt.getInt(1);
			// result = stmt.getInt(1);
		} catch (Exception e) {
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "] 执行出错" + produceName, e);
			result = -100;
		} finally {
			closeConn(stmt);
			this.dbMgr.lock.unlock();
		}

		return result;
	}

	/**
	 * 系统全局的配置的CValue
	 * 
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		return getConfig(key).CValue;
	}

	/**
	 * 系统全局的配置的FValue
	 * 
	 * @param key
	 * @return
	 */
	public float getFloat(String key) {
		return getConfig(key).FValue;
	}

	/**
	 * 系统全局的配置的CValue的数字形式
	 * 
	 * @param key
	 * @return
	 */
	public int getInt(String key) {
		return Integer.valueOf(getString(key));
	}

	String sql_LoginCheckAccount = "select idx,Password,Gender from AccountTable WHERE  Account=? ;";

	// <-----AccountDB--------
	public boolean loginCheckAccount(UserInfoEntity user) {
		boolean result = false;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(DBMgr.AccountDB);
			pstmt = this.execQuery2(sql_LoginCheckAccount, user.userName);
			if (pstmt != null) {
				rs = pstmt.executeQuery();
				if (rs.last()) {
					user.AccountId = rs.getInt("idx");
					user.sex = rs.getByte("Gender");
					if (user.password.equals(rs.getString("Password")))
						result = true;
				}
			}
		} catch (SQLException e) {
			result = false;
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "] 执行出错" + sql_LoginCheckAccount, e);
		} finally {
			closeConn(pstmt, rs);
			this.dbMgr.lock.unlock();
		}
		return result;
	}

	public int checkOnlyLogin(UserInfoEntity user) {
		return executeProcedureReturn("GameServerCheckAllow", DBMgr.AccountDB, user.userName, user.key, GameData.SERVER.ServerIndex);
	}

	public boolean clearOnlyLogin() {
		return executeProcedureReturn("GameServerClearOnly", DBMgr.AccountDB, GameData.SERVER.ServerIndex) == 1;
	}

	public void addUserFirstLogin(UserInfoEntity user) {
		user.userId = this.executeInsert("sp_AddUserInfo", DBMgr.TexasPokerDB, user.AccountId, GameData.SERVER.ServerId, user.userName, user.nickName, user.sex, user.icon);
	}

	String sql_GetUserMoney = " SELECT  MoneyNum FROM [AccountDB].[dbo].PlayInfo where  idx=?";

	/**
	 * 得到玩家最新的钱，并且转换为游戏的money
	 * 
	 * @param accountId
	 * @return
	 */
	public float getUserMoney(int accountId) {
		Connection conn = null;
		float money = 0;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		this.dbMgr.lock.lock();
		try {
			this.dbMgr.setCurrentDb(DBMgr.AccountDB);
			conn = openConn();
			if (conn == null) {
				return 0;
			}
			// 预编译SQL语句,只编译一回,效率高啊
			pstmt = conn.prepareStatement(sql_GetUserMoney, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
			pstmt.setObject(1, accountId);
			pstmt.execute();
			rs = pstmt.getResultSet();
			if (rs != null && rs.next()) {
				money = rs.getFloat(1);
			}

		} catch (Exception ex) {
			String msg = String.format("[DataBase] 提示消息:%s; 错误描述:%s; 当前状态:%s", new Object[] { "当前Sql语句出错", ex.getMessage(), "调用Sql语句" + sql_GetUserMoney + "出错" });
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + msg, ex);
		} finally {
			closeConn(conn, pstmt);
			this.dbMgr.lock.unlock();
		}
		return Math.round(money * GameData.StakeToMoney);
	}

	// -------AccountDB------>
	// <-----ServerDB--------
	public boolean getServerInfo() {
		String sqlText = "select ip1,ip2,port,MaxPopulation from GameServerList WHERE  ServerIndex=? ;";
		this.dbMgr.lock.lock();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		boolean result = false;
		try {
			this.dbMgr.setCurrentDb(DBMgr.ServerDB);
			pstmt = this.execQuery2(sqlText, GameData.SERVER.ServerIndex);
			if (pstmt != null) {
				rs = pstmt.executeQuery();
				if (rs.last()) {
					GameData.SERVER.ServerIp = rs.getString("ip1");
					GameData.SERVER.ServerIp2 = rs.getString("ip2");
					GameData.SERVER.Port = rs.getInt("port");
					GameData.SERVER.SessionMaxCount = rs.getInt("MaxPopulation");
					result = true;
				}
			}
		} catch (SQLException e) {
			result = false;
			Log.error("[DataBase][database:" + dbMgr.getCurrentDbName() + " dbindex:" + dbMgr.index + "] 执行出错" + sqlText, e);
		} finally {
			closeConn(pstmt, rs);
			this.dbMgr.lock.unlock();
		}
		return result;
	}
	// -------ServerDB------>
}
